001 package net.sf.xdc.util;
002
003 /*
004 * Copyright 2005-2006 Jens Voß.
005 *
006 * Licensed under the GNU Lesser General Public License (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://opensource.org/licenses/lgpl-license.php
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.File;
020 import java.io.FileReader;
021 import java.io.IOException;
022 import java.io.Reader;
023 import java.util.List;
024 import java.util.Vector;
025
026 /**
027 * A <code>FileTokenizer</code> is used to parse an options file for the XDC
028 * tool (which is specified with the '@' notation as a command line argument).
029 *
030 * @author Jens Voß
031 * @since 0.5
032 * @version 0.5
033 */
034 public class FileTokenizer {
035
036 private File file;
037
038 /**
039 * Public constructor.
040 *
041 * @param file The file containing the XDC options
042 */
043 public FileTokenizer(File file) {
044 this.file = file;
045 }
046
047 /**
048 * This method does the actual parsing of the XDC options file. It breaks up
049 * the contents into tokens. The following rules apply:
050 * <ol>
051 * <li>Every character may be escaped by placing a backslash ('\') in front
052 * of it.</li>
053 * <li>Text starting with an (not escaped) hash sign ('#') and ending with a
054 * line terminator is considered a comment and is ignored.
055 * <li>Text enclosed by double quotes is considered a single token. (The
056 * quotes will be stripped by this method.)</li>
057 * <li>All whitespace characters (i.e. spaces, tabs, line terminators etc.)
058 * which are neither escaped nor part of a comment nor part of a quoted
059 * token are treated as token delimiters.
060 * </ol>
061 *
062 * @return An array of the individual tokens contained in this file
063 * @throws IOException
064 */
065 public String[] getContents() throws IOException {
066 List retVal = new Vector();
067 Reader in = null;
068 try {
069 in = new FileReader(file);
070 boolean hash = false;
071 boolean quot = false;
072 StringBuffer buf = new StringBuffer();
073 char c;
074 while ((c = (char) in.read()) != (char) -1) {
075 if (hash) {
076 if (c == '\n' || c == '\r') {
077 hash = false;
078 }
079 }
080 else if (c == '#') {
081 if (!quot) {
082 String str = buf.toString().trim();
083 if (str.length() > 0) {
084 retVal.add(str);
085 }
086 buf.setLength(0);
087 }
088 hash = true;
089 }
090 else if (c == '\\') {
091 buf.append((char) in.read());
092 }
093 else if (quot) {
094 if (c == '"') {
095 quot = false;
096 String str = buf.toString().trim();
097 if (str.length() > 0) {
098 retVal.add(str);
099 }
100 buf.setLength(0);
101 }
102 else {
103 buf.append(c);
104 }
105 }
106 else if (c == '"') {
107 quot = true;
108 String str = buf.toString().trim();
109 if (str.length() > 0) {
110 retVal.add(str);
111 }
112 buf.setLength(0);
113 }
114 else if (Character.isWhitespace(c)) {
115 String str = buf.toString().trim();
116 if (str.length() > 0) {
117 retVal.add(str);
118 }
119 buf.setLength(0);
120 }
121 else {
122 buf.append(c);
123 }
124 }
125 String str = buf.toString().trim();
126 if (str.length() > 0) {
127 retVal.add(str);
128 }
129 return (String[]) retVal.toArray(new String[retVal.size()]);
130 }
131 finally {
132 if (in != null) {
133 try {
134 in.close();
135 }
136 catch (IOException e) {
137 e.printStackTrace();
138 }
139 }
140 }
141 }
142
143 }